package com.gecko.flutter_screen_capture;

import android.app.Activity;
import android.app.Notification;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.ByteArrayOutputStream;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener;

/** FlutterScreenCapturePlugin */
public class FlutterScreenCapturePlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, ActivityResultListener {
  private static final String TAG = "FlutterScreenCapture";

  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;

  private Activity activity;

  //public static String silentMusicPath = "";

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_screen_capture");
    channel.setMethodCallHandler(this);

    //FlutterPlugin.FlutterAssets assets = flutterPluginBinding.getFlutterAssets();
    //silentMusicPath = assets.getAssetFilePathByName("assets/silent.mp3");
    //Log.i(TAG, "silent music path:" + silentMusicPath);
  }

  private ScreenCapture.ImageListener mImageListener = new ScreenCapture.ImageListener() {
    @Override
    public void onImageAvailable(Bitmap bitmap) {
      ByteArrayOutputStream stream = new ByteArrayOutputStream();
      bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
      final byte[] byteArray = stream.toByteArray();
      activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
          channel.invokeMethod("onFrameUpdate", byteArray);
        }
      });
      bitmap.recycle();
    }
  };

  private ScreenCapture.StateListener mStateListener = new ScreenCapture.StateListener() {
    @Override
    public void onStateChanged(final boolean state) {
      activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
          channel.invokeMethod("onStateChanged", state);
        }
      });
    }
  };


  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if (call.method.equals("start")) {
      start();
      result.success(null);
    } else if (call.method.equals("stop")) {
      stop();
      result.success(null);
    } else {
      result.notImplemented();
    }
  }

  private void start() {
    ScreenCapture.inst(activity).start();
    Intent intent = new Intent(activity, KeepAliveService.class);
    activity.startService(intent);
  }

  private void stop() {
    ScreenCapture.inst(activity).stop();
    //Intent intent = new Intent(activity, KeepAliveService.class);
    //activity.stopService(intent);

    Intent intent = new Intent(KeepAliveService.ACTION_CMD);
    intent.putExtra(KeepAliveService.EXTRA_CMD, KeepAliveService.CMD_STOP);
    activity.sendBroadcast(intent);
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }

  @Override
  public void onAttachedToActivity(ActivityPluginBinding binding) {
    binding.addActivityResultListener(this);
    activity = binding.getActivity();
    ScreenCapture screenCapture = ScreenCapture.inst(activity);
    screenCapture.setImageListener(mImageListener);
    screenCapture.setStateListener(mStateListener);
  }

  @Override
  public void onDetachedFromActivity() {

  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {
    onDetachedFromActivity();
  }

  @Override
  public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
    onAttachedToActivity(binding);
  }

  @Override
  public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == ScreenCapture.REQUEST_MEDIA_PROJECTION && resultCode == Activity.RESULT_OK) {
      ScreenCapture.setResultData(data);
      Log.i(TAG, "onActivityResult() screen capture permission ok");
      return true;
    }
    return false;
  }
}
